package com.cdk8s.example.simplespringboot.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.HashMap;

@Slf4j
public final class JsonUtil {

	private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

	/**
	 * fastjson 转换通用对象
	 */
	public static JSONObject toJSONObjectByFastJson(String str) {
		JSONObject jsonObject;
		try {
			jsonObject = JSON.parseObject(str);
		} catch (Exception e) {
			log.error("------zch------convert JSONObject failure", e);
			throw new RuntimeException(e);
		}
		return jsonObject;
	}

	/**
	 * fastjson 转换通用对象
	 */
	public static JSONArray toJSONArrayByFastJson(String str) {
		JSONArray jsonArray;
		try {
			jsonArray = JSON.parseArray(str);
		} catch (Exception e) {
			log.error("------zch------convert JSONArray failure", e);
			throw new RuntimeException(e);
		}
		return jsonArray;
	}


	/**
	 * fastjson 转换通用对象列表
	 */
	public static JSONArray toJsonArrayByFastJson(String str) {
		JSONArray jsonArray;
		try {
			jsonArray = JSON.parseArray(str);
		} catch (Exception e) {
			log.error("------zch------convert JSONArray failure", e);
			throw new RuntimeException(e);
		}
		return jsonArray;
	}

	/**
	 * 将 POJO 转为 JSON
	 */
	public static <T> String toJson(T obj) {
		String json;
		try {
			json = OBJECT_MAPPER.writeValueAsString(obj);
		} catch (Exception e) {
			log.error("------zch------convert POJO to JSON failure", e);
			throw new RuntimeException(e);
		}
		return json;
	}

	/**
	 * 将 POJO 转为 JSON 带格式化
	 */
	public static <T> String toJsonPretty(T obj) {
		String json;
		try {
			json = OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
		} catch (Exception e) {
			log.error("------zch------convert POJO to JSON failure", e);
			throw new RuntimeException(e);
		}
		return json;
	}

	/**
	 * 将 JSON 转为 POJO
	 */
	public static <T> T toObject(String json, Class<T> type) {
		T pojo;
		try {
			pojo = OBJECT_MAPPER.readValue(json, type);
		} catch (Exception e) {
			log.error("convert JSON to POJO failure", e);
			throw new RuntimeException(e);
		}
		return pojo;
	}

	/**
	 * 将 JSON 转为 List
	 * eg：
	 * List<TopHotInfo> topHotInfos = JsonUtil.toList(readFileToString, new TypeReference<List<TopHotInfo>>() {});
	 */
	public static <T> T toList(String json, TypeReference<T> type) {
		if (StringUtil.isBlank(json)) {
			return null;
		}
		try {
			// 忽略不存在的元素
			OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
			return OBJECT_MAPPER.readValue(json, type);
		} catch (IOException e) {
			log.error("convert JSON to List failure", e);
			throw new RuntimeException(e);
		}
	}

	/**
	 * 简单 key,value 类型转换
	 * HashMap<String, String> resultMap = JsonUtil.toMap(responseData, String.class, String.class);
	 *
	 * @param json
	 * @param keyType
	 * @param valueType
	 * @param <K>
	 * @param <V>
	 * @return
	 */
	public static <K, V> HashMap<K, V> toMap(String json, Class<K> keyType, Class<V> valueType) {
		try {
			// 忽略不存在的元素
			OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
			return OBJECT_MAPPER.readValue(json, new TypeReference<HashMap<K, V>>() {
			});
		} catch (IOException e) {
			log.error("convert JSON to Map failure", e);
			throw new RuntimeException(e);
		}
	}

	/**
	 * 复杂 Map<String, List<DefUrl>> 类型转换
	 * Map<String, List<DefUrl>> mapResult = JsonUtil.toMap(readFileToString, new TypeReference<HashMap<String,List<DefUrl>>>() {});
	 * @param json
	 * @param type
	 * @param <K>
	 * @param <V>
	 * @return
	 */
	public static <K, V> HashMap<K, V> toMap(String json, TypeReference<HashMap<K, V>> type) {
		try {
			// 忽略不存在的元素
			OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
			return OBJECT_MAPPER.readValue(json, type);
		} catch (IOException e) {
			log.error("convert JSON to Map failure", e);
			throw new RuntimeException(e);
		}
	}

}
